package action.learn;/* 数据分配

        输入：交易明细，现金总额，pos总额

        创建一个数组，作为交易明细数据

        读取数组长度，及为用户数
        创建pos金额明细数组，数组长度从1开始->将每笔交易明细放入数组，与总额判断->相等，输出数组退出循环
        ->不等，pos金额明细数组长度加一，所有数组内容排列组合，若所有元素之和与pos金额->相等，输出数组退出循环
        ->不等，pos金额明细数组长度加一。。。。

        排列组合：
        用数组的index进行递归*/


import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.Stack;

public class typedivision3 {
    static int[] posidd = null;//接受下标

    static class StopMsgException extends RuntimeException {
    }

    public static Stack<Integer> stack = new Stack<Integer>();


    public static void main(String[] args) {



        ArrayList<GasOrderDto> danhao = new ArrayList<>();
        danhao.add(new GasOrderDto(1l,new BigDecimal(23.24)));

        danhao.add(new GasOrderDto(2l,new BigDecimal(30d)));

        danhao.add(new GasOrderDto(3l,new BigDecimal(93.10)));

        danhao.add(new GasOrderDto(4l,new BigDecimal(340d)));

        danhao.add(new GasOrderDto(5l,new BigDecimal(64.4)));

        danhao.add(new GasOrderDto(6l,new BigDecimal(145.01)));

        danhao.add(new GasOrderDto(7l,new BigDecimal(340.1)));

        danhao.add(new GasOrderDto(8l,new BigDecimal(237d)));

        danhao.add(new GasOrderDto(9l,new BigDecimal(43.64)));

        danhao.add(new GasOrderDto(10l,new BigDecimal(43.24)));

        danhao.add(new GasOrderDto(11l,new BigDecimal(20d)));

        danhao.add(new GasOrderDto(12l,new BigDecimal(400d)));

        //double[] danhao = {23.24,30,93.10,340,64.4,145.01,340.1,237,43.64,43.24,20,400};
        double cash = 360;//现金总额
        double pos = 1419.73;//pos总额

        int[] index = new int[danhao.size()];//创建数组，数组元素代表金额明细在danhao数组中的下标
        Long[] posmoney = null;
        Long[] cashmoney = null;
        for (int j = 0; j < index.length; j++) {
            index[j] = j;
//            System.out.println(index[j]);
        }


        if (pos!=0) {
            for (int i = 1; i <danhao.size()+1; i++) {
                int[] posid = new int[i];//创建pos支付明细数组，数组长度递增

                try {
                    pailie(danhao, posid, index, posid.length, 0, 0, pos);
                } catch (StopMsgException e) {
                    break;
                }

            }

        }
        //cash下标数组
        int[] cashidd = new int[index.length - posidd.length];
        int k = 0;
        for (int i = 0; i <index.length ; i++) {
            if(yn1(index[i],posidd)){
                cashidd[k] = index[i];
                k++;
            }
        }

        //pos:将下标数组转换为金额
        posmoney = new Long[posidd.length];
        for (int i = 0; i <posidd.length ; i++) {
            posmoney[i] = danhao.get(posidd[i]).getId();
            System.out.println(posmoney[i]);
        }
        System.out.println("===========================");
        cashmoney = new Long[danhao.size() - posidd.length];
        for (int i = 0; i <cashmoney.length; i++) {
            cashmoney[i] = danhao.get(cashidd[i]).getId();
            System.out.println(cashmoney[i]);
        }

    }



//排列组合


    //     * @param posnum  要选多少个元素
//     * @param has   当前有多少个元素
//     * @param cur   当前选到的下标
    //
    private static void pailie (List<GasOrderDto> danhao, int[] posid, int[] index, int posnum, int has, int cur, double pos){
        if (has == posnum){
//            System.out.println(stack);
            //将栈中的数字放入posmingxi中
//            for (int i = 0; i <posnum; i++) {
//                posid[i] = stack.pop();
            int k = 0;
                Enumeration<Integer> elements = stack.elements();
                while(elements.hasMoreElements()){
                    Integer integer = elements.nextElement();
                    posid[k] = integer;
                    k++;
                }

//            }
//输出下标数组
            if(yn(danhao,posid,pos)){
                posidd = new int[posid.length];
                for (int i = 0; i <posid.length; i++) {
                    posidd[i] = posid[i];
                }
                //跳出
                throw new StopMsgException();
            }
            return ;
        }

//        递归
        for (int i = cur; i <index.length; i++) {
            if(!stack.contains(index[i])){          //判断数组中的其他位数上是否有相同元素
                stack.add(index[i]);
                pailie(danhao,posid,index,posnum,has+1,i,pos);
                stack.pop();
            }
        }
    }







    //    判断下标数组是否满足金额条件
    private  static boolean yn (List<GasOrderDto> danhao,int[] posid,double pos) {
//        for (int i = 0; i <posmingxi.length; i++) {
//            posmingxi[i] = stack.pop();
//        }
        double abc = 0;
        for (int i = 0; i < posid.length; i++) {
            abc += danhao.get(posid[i]).getPayAmount().doubleValue();
        }
        if(abc == pos){

            return true;
        }
        return false;
    }
//判断下标数组中是否有相同的数
    private  static boolean yn1 (int a,int[] b) {
        for (int i = 0; i <b.length; i++) {
            if(a == b[i]){
                return false;
            }
        }
        return true;
    }


}
